﻿/*
Dojo widget for editing a list of strings. Also see property type PropertyStringList in /Models/Properties.
*/

define([
    "dojo/_base/array",
    "dojo/_base/connect",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/parser",
    "dojo/dom-attr",

    "dijit/focus",
    "ow-epi-numberSpinner/widgets/numberSpinner",
    "dijit/_CssStateMixin",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",
    "epi-cms/legacy/LegacyDialogPopup",
    "epi-cms/widget/_HasChildDialogMixin",

    "epi/epi",
    "epi/shell/widget/_ValueRequiredMixin",
    "epi/routes",

    "dojo/text!./GeoPointSelector.html",

    "xstyle/css!./GeoPointSelector.css"

],
function (
    array,
    connect,
    declare,
    lang,
    parser,
    domAttr,

    focusManager,

    NumberSpinner,
    _CssStateMixin,
    _Widget,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,
    LegacyDialogPopup,
    _HasChildDialogMixin,

    epi,
    _ValueRequiredMixin,
    routes,

    template
) {

    return declare("ow-epi-geoProperties.widgets.GeoPointSelector", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin, _HasChildDialogMixin], {

        templateString: template,

        baseClass: "geoPointSelector",

        helptext: "Place select location",

        intermediateChanges: false,

        value: null,

        onChange: function (value) {
            // Event
        },

        postCreate: function () {
            // call base implementation
            this.inherited(arguments);

            this.mapZoomInput.set("readonly", true);
            this.lblZoom.style.display = this.isMapZoomVisible ? "" : "none";
            this.mapZoomInput.domNode.style.display = this.isMapZoomVisible ? "" : "none";

            this.connect(this.latInput, "onChange", this._onLocationChanged);
            this.connect(this.lngInput, "onChange", this._onLocationChanged);
            this.connect(this.buttonClear, "onClick", this._onClearClick);

            // translations
            this.hyperlinkSelectLocation.innerText = this.selectLocationText;
            this.lblLatitude.innerText = this.latitudeText;
            this.lblLongitude.innerText = this.longitudeText;
            this.lblZoom.innerText = this.zoomText;
            this.buttonClear.setLabel(this.clearText);
            
            domAttr.set(this.lblLatitude, "for", this.latInput.id);
            domAttr.set(this.lblLongitude, "for", this.lngInput.id);
            domAttr.set(this.lblZoom, "for", this.mapZoomInput.id);
        },

        _onClearClick: function () {
            if (this.readOnly) {
                return;
            }

            this.set("value", null);
        },

        _onLocationChanged: function (value) {
            if (!value)
                return;

            var point = {
                latitude: parseFloat(this.latInput.value),
                longitude: parseFloat(this.lngInput.value),
                mapZoom: this.value.mapZoom
            };

            var imageUrl = this._getLocationImageUrl(point);

            this._set("value", point);
            this._setImageSource(this.thumbnail, this.noLocationNode, imageUrl);
        },

        postMixInProperties: function () {
            this.inherited(arguments);
        },

        isValid: function () {
            // summary:
            //    Check if widget's value is valid.
            // tags:
            //    protected, override

            return true;
        },

        // Setter for value property
        _setValueAttr: function (value) {

            this._setImageSource(this.thumbnail, this.noLocationNode, this._getLocationImageUrl(value));
            this._setLocation(value);
            this.mapZoomInput.set("value", value ? value.mapZoom : "");

            this._set("value", value);
        },

        _getLocationImageUrl: function (geoPoint) {
            if (geoPoint) {
                var url = "//maps.googleapis.com/maps/api/staticmap?center=".concat(geoPoint.latitude, ",", geoPoint.longitude, "&zoom=", geoPoint.mapZoom, "&size=", this.googleMapsApiInfo.width, "x", this.googleMapsApiInfo.height, "&sensor=false&markers=", geoPoint.latitude, ",", geoPoint.longitude);

                if (!this.googleMapsApiKey) {
                    if (console && console.warn) {
                        console.warn("Google Maps API Key is not defined for GeoPointSelctor property.");
                    }

                    return url;
                }

                return url.concat("&key=", this.googleMapsApiKey);
            } else {
                return null;
            }
        },

        _setLocation: function (geoPoint) {
            if (geoPoint) {
                this.latInput.set("value", geoPoint.latitude);
                this.lngInput.set("value", geoPoint.longitude);
            } else {
                this.latInput.set("value", "");
                this.lngInput.set("value", "");
            }
        },

        _setReadOnlyAttr: function (value) {
            this._set("readOnly", value);
            this.buttonClear.set("disabled", value);
        },

        _setStateAttr: function (value) {
            this._set("state", value);
        },

        // Setter for intermediateChanges
        _setIntermediateChangesAttr: function (value) {
            this._set("intermediateChanges", value);
        },

        _selectLocation: function () {
            if (this.readOnly) {
                return;
            }

            this.onFocus();

            if (!this._dialog) {
                var params = this._getLegacyDialogParameters();

                var legacyDialogUrl = this._getLegacyDialogUrl();
                this._dialog = new LegacyDialogPopup(lang.mixin(params, {
                    url: legacyDialogUrl
                }));

                this.connect(this._dialog, "onCallback", this._onDialogCallback);
                this.connect(this._dialog, 'onHide', this._onDialogHide);
            }

            this.isShowingChildDialog = true;

            this._dialog.show();
        },

        _setImageSource: function (thumbnailElement, noImageElement, src) {
            thumbnailElement.src = src || "";
            dojo.style(thumbnailElement, 'display', src ? 'block' : 'none');
            dojo.style(noImageElement, 'display', src ? 'none' : 'table-cell');

            dojo.style(this.latInput, 'display', src ? 'inline-block' : 'none');
            dojo.style(this.lngInput, 'display', src ? 'inline-block' : 'none');
            dojo.style(this.buttonClear, 'display', src ? 'inline-block' : 'none');
        },

        _onDialogCallback: function (value) {
            // cancel
            if (!value) {
                return;
            }

            // insert
            if (value.closeAction === "insert" && value.marker) {
                this.set("value", value.marker);
            }
            else if (value.closeAction == "clear") {
                this.set("value", null);
            }

            this.onChange(value.marker);
        },

        destroy: function () {
            if (this._dialog) {
                this._dialog.destroyRecursive();
                delete this._dialog;
            }

            this.inherited(arguments);
        },

        _onDialogHide: function () {
            this.isShowingChildDialog = false;

            this._dialog.destroyRecursive();
            delete this._dialog;

            focusManager.focus(this.thumbnail);
        },

        _getLegacyDialogParameters: function () {
            return {
                autoFit: true,
                features: {
                    width: 700,
                    height: 500
                }
            };
        },

        _getLegacyDialogUrl: function () {

            var params = {};
            if (this.value) {
                params.geoPoint = dojo.toJson(this.value);
            }
            params.showZoom = this.isMapZoomVisible ? true : false;

            return routes.getActionPath(params, this.geoPickerDialogUrl);
        }
    });
});